package bl.tools;

import java.io.File;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import callgraph.AdjacenceElement;
import callgraph.AdjacenceList;
import callgraph.GraphReader;
import callgraph.Signature;
import callgraph.SuccessorList;

public class CallCounter {
	
	static int noClasses = 0, noPackages = 0, noMethods = 0;

	/**
	 * Passed a directory with serialized adjacency lists, this class
	 * counts the average number of different classes signatures and methods called. 
	 * @param args
	 */
	public static void main(String[] args) {
		exec(args[0]);
	}
	
	static void exec(String dir){
		String[] files = (new File(dir)).list();
		GraphReader gr = new GraphReader();
		AdjacenceList al = new AdjacenceList();
		for(String file : files){
			al = gr.readGraph(dir + "\\" + file);
			count(al);
		}
		System.out.println("In folder: " + dir);
		System.out.println("------------------");
		System.out.println("\n#GraphObjects: " + files.length);
		System.out.println("\n#Methods = " + noMethods + "\tAVG = " + noMethods / files.length);
		System.out.println("\n#Classes = " + noClasses + "\tAVG = " + noClasses / files.length);
		System.out.println("\n#Packages = " + noPackages + "\tAVG = " + noPackages / files.length);
	}

	@SuppressWarnings("unchecked")
	private static void count(AdjacenceList input) {
		HashSet<Signature> methods = new HashSet<Signature>();
		HashSet<Signature> classes = new HashSet<Signature>();
		HashSet<Signature> packages = new HashSet<Signature>();
		for(Iterator iter = input.iterator(); iter.hasNext(); ){
			Map.Entry entry = (Map.Entry) iter.next();
			SuccessorList succ = (SuccessorList) entry.getValue();
			Signature sig = ( (Signature) entry.getKey() );
			methods.add(sig);
			for(int i = 0; i < succ.size(); i++){
				AdjacenceElement ae = (AdjacenceElement) succ.get(i);
				Signature succsig = (Signature) ae.getSignature();
				methods.add(succsig);
			}
			
		}
		for(Signature method : methods){
			classes.add(method.toClass());
			packages.add(method.toPackage());
		}
		noMethods += methods.size();
		noClasses += classes.size();
		noPackages += packages.size();
	}

}
